package cn.designpattern;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

public class PiggyQuickSort {
    private final static ForkJoinPool forkJoinPool = new ForkJoinPool();

    public static void sort(int []arr) {
        sort(arr,0);
    }

    public static void sort(int []arr, int number) {
        if(arr==null || arr.length==0 || arr.length==1){
            return;
        }
        QuickTask quicklyTask = new QuickTask(0, arr.length-1, arr);
        if(number != 0){
            quicklyTask.setNumber(number);
        }
        ForkJoinTask<int[]> submit = forkJoinPool.submit(quicklyTask);
        submit.join();
    }

    public static class QuickTask extends RecursiveTask<int[]> {
        private final int left;
        private final int right;
        private final int[] array;
        public QuickTask(int left, int right, int[] array) {
            this.left = left;
            this.right = right;
            this.array = array;
        }
        private int number = 9;

        public int getNumber() {
            return number;
        }

        public void setNumber(int number) {
            this.number = number;
        }

        @Override
        protected int[] compute() {
            if (right - left >= number) {
                int i = sortCompare(left, right, array);
                QuickTask one = new QuickTask(left, i-1, array);
                QuickTask two = new QuickTask(i+1, right, array);
                ForkJoinTask<int[]> fork1 = one.fork();
                ForkJoinTask<int[]> fork2 = two.fork();
                int[] join1 = fork1.join();
                int[] join2 = fork2.join();
            }else {
                quickSort(array, left, right);
            }
            return array;
        }

        public void quickSort(int[] arr, int left, int right){
            if(left<right){
                int i = sortCompare(left, right, arr);
                quickSort(arr, left, i-1);
                quickSort(arr, i+1, right);
            }
        }

        public int sortCompare(int low, int high, int[] arr) {
            int tmp = arr[low];
            while (low < high) {
                while (low < high && arr[high] >= tmp) {
                    high--;
                }
                arr[low] = arr[high];
                while (low < high && arr[low] <= tmp) {
                    low++;
                }
                arr[high] = arr[low];
            }
            arr[low] = tmp;
            return low;
        }
    }
}

